package com.moon.game.service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;
import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;

import com.moon.game.cache.Memcached;
import com.moon.game.constants.Constants;
import com.moon.game.constants.GlobalConstants;
import com.moon.game.manager.MainLandMG;
import com.moon.game.manager.MonsterMG;
import com.moon.game.resource.model.MainLand;
import com.moon.game.resource.model.Monster;
import com.moon.game.resource.model.Npcs;
import com.moon.game.util.GDateUtils;
import com.moon.game.vos.MsgVo;



/**
 * @description 地图加载
 * @author Ranger 作者 E-mail:haozi000005@163.com
 * @version 创建时间：2012-4-29 上午10:14:33
 */
public class MainLandService {
	
	private static ConcurrentHashMap<Integer, MainLandService> mainLandMap = new ConcurrentHashMap<Integer, MainLandService>();
	
	public static MainLandService getMainLandService(int mainlandId) {
		return mainLandMap.get(mainlandId);
	}
	
	/**
	 * 获取指定大陆
	 * 
	 * @param mainlandId
	 * @return
	 */
	public static MainLand getMainLand(int mainlandId) {
		return getMainLandService(mainlandId).getMainLand();
	}
	
	/**
	 * 获取通道
	 * 
	 * @param mainlandId
	 * @return
	 */
	public static ArrayList<Integer> getPorts(int mainlandId) {
		return getMainLandService(mainlandId).getPorts();
	}
	
	/**
	 * 获取npc
	 * 
	 * @param mainlandId
	 * @return
	 */
	public static ArrayList<Npcs> getNpcs(int mainlandId) {
		return getMainLandService(mainlandId).getNpcs();
	}

	private MainLandService(int mainLandId) {
		this.mainLandId = mainLandId;
		mainLand = MainLandMG.instance.getMainLand(mainLandId);
		setPorts(MainLandMG.instance.getMainLandPors(mainLandId));
		setNpcs(MainLandMG.instance.getNpcList(mainLandId));
		//加载boss
		final ArrayList<Monster> monsterRes = MonsterMG.instance.getMonsterByLeve(mainLand.getLevel() / 10 + 1);
		for (final Monster monster : monsterRes) {
			if (monster.getReviveTime() > 0) {
				/*Monster newMonster = MonsterMG.instance.monsterFactory(monster.getId());
				monsters.put(newMonster.getMonsterId(), newMonster);*/
				addMonsterToLand(monster.getId(), this.mainLandId);
			}
		}
	}
	
	public static void init(int mainLandId) {
		MainLandService loader = new MainLandService(mainLandId);
		mainLandMap.put(mainLandId, loader);
		loader.startTask();
	}

	private ConcurrentHashMap<String, Monster> monsters = new ConcurrentHashMap<String, Monster>();
	public ConcurrentHashMap<String, Monster> getMonsters() {
		return monsters;
	}

	private int GET_CHAT_PERIOD = 5 * 1000;
	private int CHECK_MONSTER_PERIOD = 1000 * 6;
	private final int monsterNumMin = 500;//该地图的怪物数量最小值
	private MainLand mainLand;
	public MainLand getMainLand() {
		return mainLand;
	}

	private int mainLandId;
	private LinkedList<MsgVo> chatPublicList = new LinkedList<MsgVo>();
	private ArrayList<Integer> ports = new ArrayList<Integer>();
	private ArrayList<Npcs> npcs = new ArrayList<Npcs>();

	public ArrayList<Integer> getPorts() {
		return ports;
	}

	private void setPorts(ArrayList<Integer> ports) {
		this.ports = ports;
	}

	public ArrayList<Npcs> getNpcs() {
		return npcs;
	}

	private void setNpcs(ArrayList<Npcs> npcs) {
		this.npcs = npcs;
	}

	public LinkedList<MsgVo> getChatPublicList() {
		return chatPublicList;
	}

	public void setChatPublicList(LinkedList<MsgVo> chatPublicList) {
		this.chatPublicList = chatPublicList;
	}

	private static Timer timer = new Timer();

	private void startTask() {
		//聊天检测5秒钟一次
		timer.scheduleAtFixedRate(new TimerTask() {
			@Override
			public void run() {
				reloadMessage();
			}
		}, 1, GET_CHAT_PERIOD);
		//怪物检测1分钟一次
		timer.scheduleAtFixedRate(new TimerTask() {
			@Override
			public void run() {
				checkMonsterNum();
				checkMonsterStatus();
			}
		}, 1, CHECK_MONSTER_PERIOD);
	}
	
	/**
	 * 加载本大陆的聊天消息
	 */
	@SuppressWarnings("unchecked")
	private void reloadMessage() {
		String key = Constants.CHAT_PUBLIC_KEY + mainLandId;
		LinkedList<MsgVo> msgs = (LinkedList<MsgVo>) Memcached.get(GlobalConstants.POOL_NAME_CHAT, key);
		if (msgs != null && msgs.size() > 0) {
			setChatPublicList(msgs);
		}
	}

	/**
	 * 加载该大陆的怪物(等级越低的怪加载出来的概率越高)
	 * 
	 */
	private void checkMonsterNum() {
		if (mainLand.getLevel() == 0) {
			//主城不需要加载怪物
			return;
		}
		if (monsters.size() >= monsterNumMin) {
			return;
		}
		final ArrayList<Monster> monsterRes = MonsterMG.instance.getMonsterByPropertyAndLevel(mainLand.getProperty(), mainLand.getLevel());
		int sum = 0;
		for (Monster mon : monsterRes) {
			if (mon.getReviveTime() > 0) {
				continue;
			}
			sum += mon.getLevel();
		}
		HashMap<Monster, HashMap<Integer, Integer>> tempMap = new HashMap<Monster, HashMap<Integer, Integer>>();
		int base = 0;
		Monster lastPollMonster = null;
		for (Monster mon : monsterRes) {
			if (mon.getReviveTime() > 0) {
				continue;
			}
			int gapLevel = sum - mon.getLevel();
			HashMap<Integer, Integer> childMap = new HashMap<Integer, Integer>();
			if (tempMap.size() == 0 || lastPollMonster == null) {
				childMap.put(0, gapLevel);
				tempMap.put(mon, childMap);
			}else {
				int lastGap = 0;
				for (Map.Entry<Integer, Integer> range : tempMap.get(lastPollMonster).entrySet()) {
					lastGap = range.getValue();
				}
				childMap.put(lastGap + 1, lastGap + gapLevel);
				tempMap.put(mon, childMap);
			}
			base += gapLevel;
			lastPollMonster = mon;
		}
		
		
		Random random = new Random();
		if (monsters.size() < monsterNumMin) {
			for (int i = 0; i < monsterNumMin / 5; i++) {
				int index = random.nextInt(base);
				for (Map.Entry<Monster, HashMap<Integer, Integer>> entryRes : tempMap.entrySet()) {
					HashMap<Integer, Integer> range = entryRes.getValue();
					for (Map.Entry<Integer, Integer> entry : range.entrySet()) {
						if (entry.getValue() < index) {
							continue;
						}
						if (entry.getKey() <= index && entry.getValue() >= index) {
							/*Monster newMonster = MonsterMG.instance.monsterFactory(entryRes.getKey().getId());
							monsters.put(newMonster.getMonsterId(), newMonster);*/
							addMonsterToLand(entryRes.getKey().getId(), this.mainLandId);
						}
					}
				}
			}
		}
	}
	
	/**
	 * 检查内存中怪物状态，普通怪物超过一分钟没有受到攻击归还到内存，boss超过复活时间(如果死亡)复活怪物
	 */
	private void checkMonsterStatus() {
		for (Map.Entry<String, Monster> monsterEntry : monsters.entrySet()) {
			Monster monster = monsterEntry.getValue();
			int lastFightTime = monster.getLastFightTime();
			//超过1分钟没有受到攻击还回内存让其他人可以攻击
			if (lastFightTime > 0 && lastFightTime + CHECK_MONSTER_PERIOD < GDateUtils.now()) {
				monsterEntry.getValue().setLastFightTime(0);
				monsterEntry.getValue().setFighter(null);
			}
			//检测boss死亡时间，超过复活时间还回内存
			if (monster.getDeadTime() > 0 && monster.getDeadTime() + monster.getReviveTime() < GDateUtils.now()) {
				monster.setDeadTime(0);
				String uuid = UUID.randomUUID().toString();
				monster.setMonsterId(uuid);
				monsters.put(uuid, monster);
			}
		}
	}
	
	/**
	 * 添加指定的怪物到指定的大陆
	 * 
	 * @param monsterId 怪物id
	 * @param landId 大陆id
	 * 
	 * @return Monster 返回添加到内存的怪物
	 */
	public static Monster addMonsterToLand(int monsterId, int landId) {
		MainLandService landService = getMainLandService(landId);
		Monster newMonster = MonsterMG.instance.monsterFactory(monsterId);
		landService.getMonsters().put(newMonster.getMonsterId(), newMonster);
		return newMonster;
	}
	
}
